
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BGroupBox>
#include <BStyle>
#include <BPicker>
#include <BCamera>
#include <BMouseEvent>
#include <BViewer>
#include <BRender>
#include <BHBoxLayout>
#include <BDockLayout>
#include <BStyle>

#include "../StringUtils.h"
#include "SliderRestraintPanel.h"

SliderRestraintPanel::SliderRestraintPanel(BWidget* parent) : BWidget(parent)
{
	BGroupBox* axisGroupBox = new BGroupBox("Axis Setting");
	{
		BLabel* axisALabel = new BLabel("axisA");
		_axisAEdit = new BLineEdit();

		BLabel* axisBLabel = new BLabel("axisB");
		_axisBEdit = new BLineEdit();

		BGridLayout* gridLayout = new BGridLayout(axisGroupBox);
		gridLayout->addWidget(0, 0, axisALabel);
		gridLayout->addWidget(0, 1, _axisAEdit);
		gridLayout->addWidget(1, 0, axisBLabel);
		gridLayout->addWidget(1, 1, _axisBEdit);
	}

	BGroupBox* limitGroupBox = new BGroupBox("Limit Setting");
	{
		BLabel* linearLimitLabel = new BLabel("linear limit");
		_linearMinSpinBox = new BRealSpinBox();
		_linearMaxSpinBox = new BRealSpinBox();

		BLabel* angleLimitLabel = new BLabel("angle limit");
		_angularMinSpinBox = new BRealSpinBox();
		_angularMaxSpinBox = new BRealSpinBox();

		BGridLayout* gridLayout = new BGridLayout(limitGroupBox);
		gridLayout->addWidget(4, 0, linearLimitLabel);
		gridLayout->addWidget(4, 1, _linearMinSpinBox);
		gridLayout->addWidget(4, 2, _linearMaxSpinBox);
		gridLayout->addWidget(5, 0, angleLimitLabel);
		gridLayout->addWidget(5, 1, _angularMinSpinBox);
		gridLayout->addWidget(5, 2, _angularMaxSpinBox);
	}

	BGroupBox* advanceGroupBox = new BGroupBox("Advance");
	{
		BLabel* softnessLabel = new BLabel("Softness");
		_limitSoftnessSpinBox = new BRealSpinBox();

		BLabel* biasFactorLabel = new BLabel("Bias Factor");
		_biasFactorSpinBox = new BRealSpinBox();

		BLabel* relaxFactorLabel = new BLabel("Relax Factor");
		_relaxFactorSpinBox = new BRealSpinBox();

		BGridLayout* gridLayout = new BGridLayout(advanceGroupBox);
		gridLayout->addWidget(1, 0, softnessLabel);
		gridLayout->addWidget(1, 1, _limitSoftnessSpinBox);
		gridLayout->addWidget(2, 0, biasFactorLabel);
		gridLayout->addWidget(2, 1, _biasFactorSpinBox);
		gridLayout->addWidget(3, 0, relaxFactorLabel);
		gridLayout->addWidget(3, 1, _relaxFactorSpinBox);
	}

	_motorGroupBox = new BGroupBox("Motor");
	_motorGroupBox->setCheckable(true);
	_motorGroupBox->setChecked(true);
	{
		BLabel* targetVelocityLabel = new BLabel("Target Velocity");
		_motorVelocitySpinBox = new BRealSpinBox();

		BLabel* maxImpulseLabel = new BLabel("Max Impulse");
		_maxImpulseSpinBox = new BRealSpinBox();

		BGridLayout* gridLayout = new BGridLayout(_motorGroupBox);
		gridLayout->addWidget(2, 0, targetVelocityLabel);
		gridLayout->addWidget(2, 1, _motorVelocitySpinBox);
		gridLayout->addWidget(3, 0, maxImpulseLabel);
		gridLayout->addWidget(3, 1, _maxImpulseSpinBox);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addWidget(axisGroupBox);
	vlayout->addWidget(limitGroupBox);
	vlayout->addWidget(advanceGroupBox);
	vlayout->addWidget(_motorGroupBox);

	connect(this, Signal_AssetChanged, &SliderRestraintPanel::slotAssetChanged);

	connect(_axisAEdit, Signal_EditFinished, &SliderRestraintPanel::slotAxisAEditFinished);
	connect(_axisBEdit, Signal_EditFinished, &SliderRestraintPanel::slotAxisBEditFinished);

	connect(_linearMinSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotLinearLimitEditFinished);
	connect(_linearMaxSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotLinearLimitEditFinished);
	connect(_angularMinSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotAngularLimitEditFinished);
	connect(_angularMaxSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotAngularLimitEditFinished);

	connect(_limitSoftnessSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotLimitSoftnessEditFinished);
	connect(_biasFactorSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotLimitBiasEditFinsihed);
	connect(_relaxFactorSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotLimitRelaxFactorEditFinihsed);

	connect(_motorGroupBox, Signal_Toggled, &SliderRestraintPanel::slotMotorEnabledToggled);
	connect(_motorVelocitySpinBox, Signal_EditFinished, &SliderRestraintPanel::slotTargetVelocityEditFinished);
	connect(_maxImpulseSpinBox, Signal_EditFinished, &SliderRestraintPanel::slotMaxImpulseEditFinished);
}
SliderRestraintPanel::~SliderRestraintPanel()
{

}

void SliderRestraintPanel::slotAssetChanged(BObject* object, const BValue& value)
{
	BSliderRestraint* restraint = value;
	if (_sliderRestraint != restraint)
	{
		if (_sliderRestraint)
			disconnect(_sliderRestraint);
		_sliderRestraint = restraint;
		if (_sliderRestraint)
		{
			connect(_sliderRestraint, Signal_Changed, &SliderRestraintPanel::slotSliderRestraintChanged);

			const BRealRange& linearLimit = _sliderRestraint->linearLimit();
			_linearMinSpinBox->setValue(linearLimit.min());
			_linearMaxSpinBox->setValue(linearLimit.max());

			const BRealRange& angularLimit = _sliderRestraint->angularLimit();
			_angularMinSpinBox->setValue(angularLimit.min());
			_angularMaxSpinBox->setValue(angularLimit.max());

			_axisAEdit->setText(StringFromVector(_sliderRestraint->axisA()));
			_axisBEdit->setText(StringFromVector(_sliderRestraint->axisB()));
		}
		else
		{

		}
	}
}
void SliderRestraintPanel::slotSliderRestraintChanged(BObject* object, const BValue& value)
{
	const BRealRange& linearLimit = _sliderRestraint->linearLimit();
	_linearMinSpinBox->setValue(linearLimit.min());
	_linearMaxSpinBox->setValue(linearLimit.max());

	const BRealRange& angularLimit = _sliderRestraint->angularLimit();
	_angularMinSpinBox->setValue(angularLimit.min());
	_angularMaxSpinBox->setValue(angularLimit.max());

	_axisAEdit->setText(StringFromVector(_sliderRestraint->axisA()));
	_axisBEdit->setText(StringFromVector(_sliderRestraint->axisB()));
}

void SliderRestraintPanel::slotAxisAEditFinished(BObject* object, const BValue& value)
{
	const BString& text = value;
	BVector axisA = StringToVector(text);
	_sliderRestraint->setAxisA(axisA);
}
void SliderRestraintPanel::slotAxisBEditFinished(BObject* object, const BValue& value)
{
	const BString& text = value;
	BVector axisB = StringToVector(text);
	_sliderRestraint->setAxisB(axisB);
}

void SliderRestraintPanel::slotLinearLimitEditFinished(BObject* object, const BValue& value)
{
	BReal min = _linearMinSpinBox->value();
	BReal max = _linearMaxSpinBox->value();
	_sliderRestraint->setLinearLimit(min, max);
}
void SliderRestraintPanel::slotAngularLimitEditFinished(BObject* object, const BValue& value)
{
	BReal min = _angularMinSpinBox->value();
	BReal max = _angularMaxSpinBox->value();
	_sliderRestraint->setAngularLimit(min, max);
}
void SliderRestraintPanel::slotLimitSoftnessEditFinished(BObject* object, const BValue& value)
{
	BReal softness = value;
}
void SliderRestraintPanel::slotLimitBiasEditFinsihed(BObject* object, const BValue& value)
{
	BReal biasFactor = value;
}
void SliderRestraintPanel::slotLimitRelaxFactorEditFinihsed(BObject* object, const BValue& value)
{
	BReal relaxFactor = value;
}

void SliderRestraintPanel::slotMotorEnabledToggled(BObject* object, const BValue& value)
{
	bool motorEnabled = value;

}
void SliderRestraintPanel::slotTargetVelocityEditFinished(BObject* object, const BValue& value)
{
	BReal targetVelocity = value;

}
void SliderRestraintPanel::slotMaxImpulseEditFinished(BObject* object, const BValue& value)
{
	BReal maxImpulse = value;

}

void SliderRestraintPanel::styleEvent(const BEvent& event)
{
	if (const BStyle* style = event.value())
	{

	}
}
